from fastapi import FastAPI, File, UploadFile, Form, HTTPException, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from fastapi.responses import HTMLResponse, FileResponse, StreamingResponse
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.responses import Response
import uvicorn
import os
import asyncio
import json
from typing import Any, Dict
from pathlib import Path

from app.config import settings
from app.services.internvl_service import InternVLService
from app.services.qwen_service import QwenVLService
from app.services.video_service import VideoService
from app.services.report_service import ReportService
from app.services.video_manager import VideoManager
from app.services.large_video_analyzer import LargeVideoAnalyzer
from app.services.text_llm_service import TextLLMService
from app.models.schemas import AnalysisRequest, AnalysisResponse
from app.utils.logger import logger

# 视频分段访问日志中间件
class VideoSegmentLoggingMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request: Request, call_next):
        # 记录对视频分段的访问
        if request.url.path.startswith("/videos/segments/"):
            client_ip = request.client.host if request.client else "unknown"
            user_agent = request.headers.get("user-agent", "unknown")
            logger.info(f"视频分段访问: {request.method} {request.url.path} - 来源IP: {client_ip} - User-Agent: {user_agent}")
        
        response = await call_next(request)
        
        # 记录404错误的分段访问
        if request.url.path.startswith("/videos/segments/") and response.status_code == 404:
            client_ip = request.client.host if request.client else "unknown"
            logger.warning(f"视频分段404错误: {request.url.path} - 来源IP: {client_ip}")
        
        return response

# 创建FastAPI应用
app = FastAPI(
    title="视频理解分析工具 M0",
    description="基于InternVL3.5的智能视频理解分析平台",
    version="0.1.0"
)

# 添加中间件
app.add_middleware(VideoSegmentLoggingMiddleware)

# CORS中间件
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 静态文件服务
app.mount("/static", StaticFiles(directory="static"), name="static")
# 视频文件服务 - 让上传的视频可以通过URL访问
app.mount("/videos", StaticFiles(directory="uploads"), name="videos")
# 视频分段文件服务
app.mount("/videos/segments", StaticFiles(directory="uploads/segments"), name="segments")

# 初始化服务
internvl_service = InternVLService()  # 主力模型
qwen_service = QwenVLService()  # 备用模型
text_llm_service = TextLLMService()  # 通用文本LLM（OpenAI兼容）
video_service = VideoService()
report_service = ReportService()
video_manager = VideoManager()
large_video_analyzer = LargeVideoAnalyzer()

@app.get("/", response_class=HTMLResponse)
async def root():
    """主页面"""
    return FileResponse("static/index.html")

@app.get("/test", response_class=HTMLResponse)
async def test_page():
    """测试页面"""
    return FileResponse("static/test_upload.html")

@app.get("/large-analysis", response_class=HTMLResponse)
async def large_analysis_page():
    """大视频分析页面"""
    return FileResponse("static/large_video_analysis.html")

@app.post("/api/analyze", response_model=AnalysisResponse)
async def analyze_video(
    file: UploadFile = File(...),
    prompt: str = Form(...),
    template_name: str = Form(default="general")
):
    """视频分析API"""
    try:
        logger.info(f"开始分析视频: {file.filename}")
        
        # 1. 验证文件
        if not video_service.validate_file(file):
            raise HTTPException(status_code=400, detail="不支持的文件格式或文件过大")
        
        # 2. 保存上传文件并获取访问URL
        file_path, video_url = await video_service.save_upload_file(file)
        
        # 3. 使用InternVL3.5作为默认模型进行分析
        try:
            logger.info(f"使用InternVL3.5分析视频: {video_url}")
            video_b64 = await video_service.convert_video_to_base64(file_path)
            video_mime_type = video_service.get_video_mime_type(file_path)
            analysis_result = await internvl_service.analyze_video_direct(
                video_b64, video_mime_type, prompt
            )
        except Exception as internvl_error:
            logger.warning(f"InternVL3.5分析失败，尝试Qwen3-VL备用方案: {internvl_error}")
            try:
                analysis_result = await qwen_service.analyze_video_by_url(video_url, prompt)
            except Exception as qwen_error:
                logger.warning(f"Qwen3-VL分析也失败，尝试帧分析兜底: {qwen_error}")
                # 最后回退到帧分析
                import cv2
                cap = cv2.VideoCapture(str(file_path))
                frames = []
                frame_count = 0
                max_frames = 8
                total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
                step = max(1, total_frames // max_frames)
                
                while frame_count < max_frames:
                    cap.set(cv2.CAP_PROP_POS_FRAMES, frame_count * step)
                    ret, frame = cap.read()
                    if not ret:
                        break
                    frame_resized = cv2.resize(frame, (448, 448))
                    _, buffer = cv2.imencode('.jpg', frame_resized, [cv2.IMWRITE_JPEG_QUALITY, 85])
                    frames.append(buffer.tobytes())
                    frame_count += 1
                
                cap.release()
                analysis_result = await internvl_service.analyze_video_frames(frames, prompt)
        
        # 5. 生成报告
        report_path = await report_service.generate_report(
            analysis_result, file.filename, prompt
        )
        
        # 6. 清理临时文件
        await video_service.cleanup_temp_files(file_path)
        
        logger.info(f"视频分析完成: {file.filename}")
        
        return AnalysisResponse(
            success=True,
            result=analysis_result,
            report_url=f"/api/download/{Path(report_path).name}",
            message="分析完成"
        )
        
    except Exception as e:
        logger.error(f"视频分析失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"分析失败: {str(e)}")

@app.get("/api/download/{filename}")
async def download_report(filename: str):
    """下载报告"""
    file_path = Path("reports") / filename
    if not file_path.exists():
        raise HTTPException(status_code=404, detail="报告文件不存在")
    
    return FileResponse(
        path=file_path,
        filename=filename,
        media_type='text/html'
    )

@app.post("/api/upload")
async def upload_video(file: UploadFile = File(...)):
    """上传视频文件并返回访问URL"""
    try:
        logger.info(f"开始上传视频: {file.filename}")
        
        # 1. 验证文件
        if not video_service.validate_file(file):
            raise HTTPException(status_code=400, detail="不支持的文件格式或文件过大")
        
        # 2. 保存上传文件并获取访问URL
        file_path, video_url = await video_service.save_upload_file(file)
        
        # 3. 获取文件信息
        file_size = file_path.stat().st_size
        filename = video_service.get_filename_from_path(file_path)
        
        logger.info(f"视频上传完成: {file.filename} -> {video_url}")
        
        return {
            "success": True,
            "message": "视频上传成功",
            "data": {
                "filename": filename,
                "original_name": file.filename,
                "file_size": file_size,
                "video_url": video_url,
                "file_path": str(file_path)
            }
        }
        
    except Exception as e:
        logger.error(f"视频上传失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"上传失败: {str(e)}")

@app.post("/api/test-qwen")
async def test_qwen_model(
    video_url: str = Form(...),
    prompt: str = Form(default="详述视频中的操作步骤，带上时间")
):
    """测试Qwen3-VL模型"""
    try:
        logger.info(f"测试Qwen3-VL模型，视频URL: {video_url}")
        
        # 使用Qwen服务进行分析
        result = await qwen_service.analyze_video_by_url(video_url, prompt)
        
        logger.info("Qwen3-VL模型调用成功")
        return {
            "success": True,
            "message": "模型调用成功",
            "result": result,
            "video_url": video_url,
            "prompt": prompt,
            "service_info": await qwen_service.get_service_info()
        }
                
    except Exception as e:
        logger.error(f"测试Qwen3-VL模型失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"测试失败: {str(e)}")

@app.get("/api/templates")
async def get_templates():
    """获取提示词模板"""
    templates = {
        "general": "请详细描述这个视频的内容，包括场景、人物、动作和主要事件。",
        "object_detection": "请识别视频中出现的所有物体和人物，并描述它们的位置和动作。",
        "scene_analysis": "请分析视频的场景设置、环境特征和氛围。",
        "action_recognition": "请识别和描述视频中发生的所有动作和行为。",
        "content_summary": "请为这个视频提供一个简洁的内容摘要。",
        "step_analysis": "详述视频中的操作步骤，带上时间"
    }
    return templates

@app.get("/api/health")
async def health_check():
    """健康检查"""
    try:
        # 测试InternVL连接（主力）
        internvl_ok = await internvl_service.test_connection()
        # 测试Qwen连接（备用）
        qwen_ok = await qwen_service.test_connection()
        
        status = "healthy" if internvl_ok else ("degraded" if qwen_ok else "unhealthy")
        
        return {
            "status": status,
            "internvl_connection": internvl_ok,
            "qwen_connection": qwen_ok,
            "primary_service": "InternVL3.5",
            "backup_service": "Qwen3-VL",
            "message": f"主服务InternVL3.5: {'正常' if internvl_ok else '异常'}, 备用服务Qwen3-VL: {'正常' if qwen_ok else '异常'}"
        }
    except Exception as e:
        return {
            "status": "unhealthy",
            "message": f"服务异常: {str(e)}"
        }

@app.get("/debug/qwen")
async def debug_qwen():
    """调试：检查Qwen3-VL服务"""
    try:
        import httpx
        
        # 获取服务信息
        service_info = await qwen_service.get_service_info()
        
        # 测试连接
        connection_test = await qwen_service.test_connection()
        
        # 尝试直接访问API
        try:
            async with httpx.AsyncClient(timeout=10.0) as client:
                response = await client.get(settings.QWEN_API_URL.replace('/api/generate', '/health'))
                health_status = response.status_code
                health_text = response.text[:200] if response.text else "无响应内容"
        except Exception as e:
            health_status = "连接失败"
            health_text = str(e)
        
        return {
            "service_info": service_info,
            "connection_test": connection_test,
            "health_check": {
                "status": health_status,
                "response": health_text
            },
            "config": {
                "api_url": settings.QWEN_API_URL,
                "model_name": settings.QWEN_MODEL_NAME
            }
        }
    except Exception as e:
        return {
            "error": str(e),
            "config": {
                "api_url": settings.QWEN_API_URL,
                "model_name": settings.QWEN_MODEL_NAME
            }
        }

@app.get("/videos")
async def video_management_page():
    """视频管理页面"""
    return FileResponse("static/video_manager.html")

@app.get("/api/videos")
async def get_video_list():
    """获取视频列表"""
    try:
        video_list = video_manager.get_video_list()
        return {
            "success": True,
            "data": video_list,
            "count": len(video_list)
        }
    except Exception as e:
        logger.error(f"获取视频列表失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"获取视频列表失败: {str(e)}")

@app.delete("/api/videos/{filename}")
async def delete_video(filename: str):
    """删除视频"""
    try:
        success = video_manager.delete_video(filename)
        if success:
            return {
                "success": True,
                "message": f"视频 {filename} 删除成功"
            }
        else:
            raise HTTPException(status_code=404, detail="视频文件不存在或删除失败")
    except Exception as e:
        logger.error(f"删除视频失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"删除视频失败: {str(e)}")

@app.get("/api/videos/{filename}")
async def get_video_info(filename: str):
    """获取视频信息"""
    try:
        video_info = video_manager.get_video_info(filename)
        if video_info:
            return {
                "success": True,
                "data": video_info
            }
        else:
            raise HTTPException(status_code=404, detail="视频不存在")
    except Exception as e:
        logger.error(f"获取视频信息失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"获取视频信息失败: {str(e)}")

@app.post("/api/videos/cleanup")
async def cleanup_orphaned_records():
    """清理孤立的视频记录"""
    try:
        cleaned_count = video_manager.cleanup_orphaned_records()
        return {
            "success": True,
            "message": f"清理了 {cleaned_count} 个孤立记录",
            "cleaned_count": cleaned_count
        }
    except Exception as e:
        logger.error(f"清理孤立记录失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"清理失败: {str(e)}")

@app.post("/api/analyze-large")
async def analyze_large_video(
    file: UploadFile = File(...),
    prompt: str = Form(...),
    split_method: str = Form(default="auto"),  # duration, scene, auto
    segment_duration: int = Form(default=60),
    max_segments: int = Form(default=20),
    analysis_mode: str = Form(default="sequential"),  # sequential, parallel, hybrid
    min_segment_duration: int = Form(default=10),  # 最小片段时长
    segment_prompt_template: str = Form(default=""),
    aggregate_prompt: str = Form(default="")
):
    """大视频分析API"""
    try:
        logger.info(f"开始大视频分析: {file.filename}")
        
        # 1. 验证文件
        if not video_service.validate_file(file):
            raise HTTPException(status_code=400, detail="不支持的文件格式或文件过大")
        
        # 2. 保存上传文件
        file_path, video_url = await video_service.save_upload_file(file)
        
        # 3. 执行大视频分析（支持用户自定义的分段/汇总提示词模板）
        analysis_result = await large_video_analyzer.analyze_large_video(
            video_path=file_path,
            prompt=prompt,
            split_method=split_method,
            segment_duration=segment_duration,
            max_segments=max_segments,
            analysis_mode=analysis_mode,
            min_segment_duration=min_segment_duration,
            segment_prompt_template=segment_prompt_template or None,
            aggregate_prompt=aggregate_prompt or None,
            progress_callback=None
        )
        
        logger.info(f"大视频分析完成: {file.filename}")
        
        return {
            "success": True,
            "result": analysis_result,
            "message": "大视频分析完成",
            "analysis_type": analysis_result.get("type", "unknown")
        }
        
    except Exception as e:
        logger.error(f"大视频分析失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"分析失败: {str(e)}")

@app.post("/api/analyze-large-stream")
async def analyze_large_video_stream(
    file: UploadFile = File(...),
    prompt: str = Form(...),
    split_method: str = Form(default="auto"),
    segment_duration: int = Form(default=60),
    max_segments: int = Form(default=20),
    analysis_mode: str = Form(default="sequential"),
    min_segment_duration: int = Form(default=10),
    segment_prompt_template: str = Form(default=""),
    aggregate_prompt: str = Form(default="")
):
    """大视频分段结果流式输出（SSE）"""
    try:
        if not video_service.validate_file(file):
            raise HTTPException(status_code=400, detail="不支持的文件格式或文件过大")
        file_path, _ = await video_service.save_upload_file(file)

        queue: asyncio.Queue = asyncio.Queue()

        async def progress_event(event: Dict[str, Any]):
            try:
                if event.get("type") == "segment_start":
                    payload = event.get("payload", {})
                    await queue.put({
                        "event": "segment_start",
                        "data": {
                            "segment_index": payload.get("segment_index"),
                            "status": event.get("status", "running"),
                            "segment_info": payload.get("segment_info", {}),
                            "started_at": payload.get("started_at"),
                            "prompt": payload.get("prompt")
                        }
                    })
                elif event.get("type") == "segment_delta":
                    payload = event.get("payload", {})
                    await queue.put({
                        "event": "segment_delta",
                        "data": {
                            "segment_index": payload.get("segment_index"),
                            "delta": payload.get("delta", "")
                        }
                    })
                elif event.get("type") == "segment_progress":
                    payload = event.get("payload", {})
                    await queue.put({
                        "event": "segment_progress",
                        "data": {
                            "segment_index": payload.get("segment_index"),
                            "status": event.get("status"),
                            "segment_info": payload.get("segment_info", {}),
                            "analyzed_at": payload.get("analyzed_at"),
                            "prompt": payload.get("prompt"),
                            "analysis_result": payload.get("analysis_result", "")
                        }
                    })
            except Exception as e:
                await queue.put({"event": "error", "data": {"message": f"progress_error: {str(e)}"}})

        async def event_generator():
            try:
                analyze_task = asyncio.create_task(
                    large_video_analyzer.analyze_large_video(
                        video_path=file_path,
                        prompt=prompt,
                        split_method=split_method,
                        segment_duration=segment_duration,
                        max_segments=max_segments,
                        analysis_mode=analysis_mode,
                        min_segment_duration=min_segment_duration,
                        segment_prompt_template=segment_prompt_template or None,
                        aggregate_prompt=aggregate_prompt or None,
                        progress_callback=progress_event
                    )
                )

                while True:
                    if analyze_task.done() and queue.empty():
                        break
                    try:
                        item = await asyncio.wait_for(queue.get(), timeout=0.3)
                        yield f"event: {item['event']}\n"
                        yield "data: " + json.dumps(item["data"], ensure_ascii=False) + "\n\n"
                    except asyncio.TimeoutError:
                        await asyncio.sleep(0.1)

                final_result = await analyze_task
                yield "event: final_result\n"
                yield "data: " + json.dumps(final_result, ensure_ascii=False) + "\n\n"
            except Exception as e:
                err = {"message": f"stream_error: {str(e)}"}
                yield "event: error\n"
                yield "data: " + json.dumps(err, ensure_ascii=False) + "\n\n"

        return StreamingResponse(event_generator(), media_type="text/event-stream")
    except Exception as e:
        logger.error(f"流式分析启动失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"流式分析失败: {str(e)}")

@app.get("/api/large-analysis/{video_id}")
async def get_large_analysis_result(video_id: str):
    """获取大视频分析结果"""
    try:
        result = large_video_analyzer.get_analysis_result(video_id)
        if result:
            return {
                "success": True,
                "data": result
            }
        else:
            raise HTTPException(status_code=404, detail="分析结果不存在")
    except Exception as e:
        logger.error(f"获取分析结果失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"获取失败: {str(e)}")

@app.post("/api/split-video")
async def split_video_endpoint(
    file: UploadFile = File(...),
    method: str = Form(default="duration"),
    segment_duration: int = Form(default=60),
    max_segments: int = Form(default=20)
):
    """视频拆分API"""
    try:
        logger.info(f"开始拆分视频: {file.filename}")
        
        # 验证和保存文件
        if not video_service.validate_file(file):
            raise HTTPException(status_code=400, detail="不支持的文件格式")
        
        file_path, _ = await video_service.save_upload_file(file)
        
        # 拆分视频
        if method == "scene":
            split_result = await large_video_analyzer.video_splitter.split_video_by_scenes(
                file_path, max_segments=max_segments
            )
        else:
            split_result = await large_video_analyzer.video_splitter.split_video_by_duration(
                file_path, segment_duration, max_segments
            )
        
        return {
            "success": True,
            "data": split_result,
            "message": f"视频拆分完成，生成 {split_result.get('segment_count', 0)} 个片段"
        }
        
    except Exception as e:
        logger.error(f"视频拆分失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"拆分失败: {str(e)}")

@app.get("/api/segments/{video_id}")
async def get_video_segments(video_id: str):
    """获取视频分段信息"""
    try:
        metadata = large_video_analyzer.video_splitter.get_segments_metadata(video_id)
        if metadata:
            return {
                "success": True,
                "data": metadata
            }
        else:
            raise HTTPException(status_code=404, detail="分段信息不存在")
    except Exception as e:
        logger.error(f"获取分段信息失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"获取失败: {str(e)}")

@app.post("/api/generate-prompts")
async def generate_prompts(original_prompt: str = Form(...)):
    """
    使用大模型将用户原始提示词改写为分段提示词模板与汇总提示词。
    输出包含两个代码块：##SEGMENT_PROMPT## 和 ##AGGREGATE_PROMPT##。
    """
    try:
        meta_prompt = """/no_think
    
你的任务：  
1. 不增删任何判定规则，仅把同一份规则改写成分段适用的“分段提示词”，要求让大模型能明白当前用户输入的视频只是总视频中的一段；  
2. 同时写一段“汇总提示词”，把各分片结果合并成符合原始格式的最终答案；  
3. 输出两个代码块，分别叫##SEGMENT_PROMPT## 和 ##AGGREGATE_PROMPT##；  
4. 两段提示词里都要保留用户要求的所有字段、取值范围、输出格式；  
5. 如果原始任务含“次数/频率”类要求，分段提示词必须输出“本地计数+时间戳列表”，汇总提示词只做累加或去重；  
6. 全程禁止添加新规，禁止解释，禁止废话。

【占位符要求】
- 在分段提示词中合理使用以下占位符用于渲染上下文：
- {base_prompt}
- {segment_id} / {segment_no} / {segment_index}
- {total_segments}
- {start_time} / {end_time}（带 s）; {start_sec} / {end_sec}（纯数字）
- {duration}
- {segment_filename} / {segment_url}
- 说明：{segment_id} 与 {segment_no} 等价（均为从 1 开始的序号），{segment_index} 从 0 开始；时间相关字段请严格按注释格式输出。

【输入】

<用户原始分析提示词>

{用户给的原版提示词全文，在这里占位}

【输出格式】

##SEGMENT_PROMPT##  

```
{分段提示词全文，需在合适位置使用上述占位符，至少包含 {base_prompt}、{segment_id}/{segment_no}、{segment_index}、{total_segments}、{start_time}、{end_time}、{start_sec}、{end_sec}、{duration}、{segment_filename}、{segment_url}}
```

##AGGREGATE_PROMPT##  

```
{汇总提示词全文，含如何把各分片 JSON 合并成最终答案的指令}
```
"""
        # 将原始提示词填入
        final_prompt = meta_prompt.replace("{用户给的原版提示词全文，在这里占位}", original_prompt)
        # 调用文本分析模型（可配置提供方）
        provider = settings.PROMPT_TEXT_PROVIDER.strip().lower() if hasattr(settings, 'PROMPT_TEXT_PROVIDER') else ''
        if provider == 'internvl':
            result_text = await internvl_service.analyze_text(final_prompt)
        elif provider in ('openai', 'text', 'custom'):
            result_text = await text_llm_service.analyze_text(final_prompt)
        else:
            # 默认或 provider=='' 仍使用 qwen
            result_text = await qwen_service.analyze_text(final_prompt)

        def extract_block(text: str, marker: str) -> str:
            import re
            # 兼容 ```、```json、```markdown 等代码块标记
            pattern = rf"##{marker}##\s*```[a-zA-Z0-9_-]*\s*(.*?)```"
            m = re.search(pattern, text, re.DOTALL)
            return m.group(1).strip() if m else ""

        # 调试日志，便于定位上游响应问题（仅打印前500字符）
        preview = (result_text[:500].replace('\n', ' ') if isinstance(result_text, str) else str(type(result_text)))
        logger.info(f"文本LLM返回长度: {len(result_text) if isinstance(result_text, str) else 'N/A'}，预览: {preview}")

        segment_template = extract_block(result_text, "SEGMENT_PROMPT")
        aggregate_template = extract_block(result_text, "AGGREGATE_PROMPT")

        # 兜底：若解析失败，则提供可用的默认模板，保证前端文本框不为空
        if not segment_template:
            segment_template = """{base_prompt}

【片段信息】
片段序号: {segment_id}/{total_segments}
时间段: {start_time} - {end_time} (时长: {duration})
文件: {segment_filename}
URL: {segment_url}
"""
        if not aggregate_template:
            aggregate_template = """将所有分片返回的 JSON 结果合并为最终答案：
- 对次数/频率做累加或去重
- 对同一字段的冲突按证据充分性（时间戳数量/清晰度）决策，否则标注无法判断
- 输出格式与原始提示词一致
"""

        return {
            "success": True,
            "segment_prompt_template": segment_template,
            "aggregate_prompt": aggregate_template,
            "raw": result_text
        }
    except Exception as e:
        import traceback
        logger.error(f"提示词生成失败: {e}\n{traceback.format_exc()}")
        # 不中断：提供兜底模板返回，避免 500 打断流程
        segment_template = """{base_prompt}

【片段信息】
片段序号: {segment_id}/{total_segments}
时间段: {start_time} - {end_time} (时长: {duration})
文件: {segment_filename}
URL: {segment_url}
"""
        aggregate_template = """将所有分片返回的 JSON 结果合并为最终答案：
- 对次数/频率做累加或去重
- 对同一字段的冲突按证据充分性（时间戳数量/清晰度）决策，否则标注无法判断
- 输出格式与原始提示词一致
"""
        return {
            "success": False,
            "segment_prompt_template": segment_template,
            "aggregate_prompt": aggregate_template,
            "raw": "",
            "message": f"提示词生成失败: {str(e)}（已返回兜底模板）"
        }

@app.delete("/api/segments/{video_id}")
async def cleanup_video_segments(video_id: str):
    """清理视频分段文件"""
    try:
        success = large_video_analyzer.video_splitter.cleanup_segments(video_id)
        if success:
            return {
                "success": True,
                "message": f"视频分段 {video_id} 清理成功"
            }
        else:
            raise HTTPException(status_code=404, detail="分段文件不存在")
    except Exception as e:
        logger.error(f"清理分段失败: {str(e)}")
        raise HTTPException(status_code=500, detail=f"清理失败: {str(e)}")

if __name__ == "__main__":
    uvicorn.run(
        "app.main:app",
        host=settings.APP_HOST,
        port=settings.APP_PORT,
        reload=settings.DEBUG
    )